package org.coody.framework.minicat.adapt;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.coody.framework.minicat.config.MiniCatConfig;
import org.coody.framework.minicat.entity.MultipartFile;
import org.coody.framework.minicat.util.ByteUtils;
import org.coody.framework.minicat.util.StringUtil;

public class ParamentBuild {

	/**
	 * 简单装载参数
	 * 
	 * @param queryString
	 * @return
	 */
	public static Map<String, List<Object>> buildGeneralParams(String queryString) {
		if (StringUtil.isNullOrEmpty(queryString)) {
			return new HashMap<String, List<Object>>();
		}
		String[] lines = queryString.split("&");
		Map<String, List<Object>> params = new HashMap<String, List<Object>>();
		for (String line : lines) {
			try {
				int index = line.indexOf("=");
				if (index < 1 || index == line.length() - 1) {
					continue;
				}
				String paramName = line.substring(0, index);
				String paramValue = URLDecoder.decode(line.substring(index + 1), MiniCatConfig.ENCODE);
				if (!params.containsKey(paramName)) {
					List<Object> paramValues = new ArrayList<Object>();
					params.put(paramName, paramValues);
				}
				params.get(paramName).add(paramValue);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return params;
	}

	/**
	 * Http协议是世界上最邋遢的协议，没有之一。
	 * 
	 * @param data
	 * @param boundary
	 * @return
	 * @throws IOException
	 */
	public static Map<String, List<Object>> buildMultipartParams(byte[] data, String boundary) {
		if (StringUtil.isNullOrEmpty(data)) {
			return new HashMap<String, List<Object>>();
		}
		String contextType = "text/plain";
		ByteArrayInputStream inputStream = new ByteArrayInputStream(data);

		String generalBoundary = "--" + boundary;

		String boundaryTag = ByteUtils.readLineString(inputStream).trim();
		while (boundaryTag != null && !boundaryTag.equals(generalBoundary)) {
			boundaryTag = ByteUtils.readLineString(inputStream).trim();
		}
		Map<String, List<Object>> paramMap = new HashMap<String, List<Object>>();
		while (boundaryTag.equals(generalBoundary)) {
			try {
				String disposition = ByteUtils.readLineString(inputStream);
				while (disposition != null && disposition.equals("\r")) {
					disposition = ByteUtils.readLineString(inputStream);
				}
				if (StringUtil.isNullOrEmpty(disposition)) {
					continue;
				}
				if (disposition.contains(":")) {
					disposition = disposition.substring(disposition.indexOf(":") + 1);
				}
				String paramName = "";
				String fileName = "";
				String[] lines = disposition.split("; ");
				for (String line : lines) {
					if (!line.contains("=")) {
						continue;
					}
					String name = line.substring(0, line.indexOf("=")).trim();
					String value = line.substring(line.indexOf("=") + 1).replace("\"", "").trim();
					if (name.equals("name")) {
						paramName = value;
						continue;
					}
					if (name.equals("filename")) {
						fileName = value;
					}
				}
				if (StringUtil.isNullOrEmpty(paramName)) {
					continue;
				}
				String line = ByteUtils.readLineString(inputStream);
				if (!line.equals("\r") && line.contains("Content-Type")) {
					contextType = line.substring(line.indexOf(":") + 1);
					if (contextType.contains(";")) {
						contextType = contextType.substring(contextType.indexOf(";") + 1);
					}
					contextType = contextType.trim();
					line = ByteUtils.readLineString(inputStream);
				}
				if (contextType.startsWith("application/") || contextType.startsWith("image/")) {
					if (StringUtil.isNullOrEmpty(fileName)) {
						continue;
					}
					List<Object> bytes = new ArrayList<Object>();
					byte[] fileData = ByteUtils.readLine(inputStream);
					String desc=new String(fileData, MiniCatConfig.ENCODE).trim();
					while ((fileData.length==0)|| !desc.startsWith(generalBoundary)) {
						bytes.add(fileData);
						fileData = ByteUtils.readLine(inputStream);
						desc=new String(fileData, MiniCatConfig.ENCODE).trim();
						System.out.println(desc);
					}
					boundaryTag = new String(fileData, MiniCatConfig.ENCODE).trim();
					fileData = listByteToBytes(bytes);
					System.out.println(fileData.length);
					MultipartFile file = new MultipartFile();
					file.setFileContext(fileData);
					file.setParamName(paramName);
					file.setFileName(fileName);
					if (!paramMap.containsKey(paramName)) {
						List<Object> files = new ArrayList<Object>();
						paramMap.put(paramName, files);
					}
					paramMap.get(paramName).add(file);
					continue;
				}
				String paramValue = ByteUtils.readLineString(inputStream);
				if (!paramMap.containsKey(paramName)) {
					List<Object> files = new ArrayList<Object>();
					paramMap.put(paramName, files);
				}
				paramMap.get(paramName).add(paramValue);
				boundaryTag = ByteUtils.readLineString(inputStream).trim();
				while (boundaryTag != null && !boundaryTag.startsWith(generalBoundary)) {
					boundaryTag = ByteUtils.readLineString(inputStream).trim();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return paramMap;
	}

	private static byte[] listByteToBytes(List<Object> bytes) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		for (int i = 0; i < bytes.size(); i++) {
			byte[] byes = (byte[]) bytes.get(i);
			if (i == bytes.size() - 1) {
				outputStream.write(byes, 0, byes.length - 1);
				continue;
			}
			outputStream.write(byes, 0, byes.length);
			outputStream.write(10);
		}
		return outputStream.toByteArray();
	}

}
